/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date             Author      Notes
 * 2021-10-29       Lyons       first version
 * 2022-04-04       Lyons       v2.0
 * 2022-07-01       Lyons       add pa_perips_tcm2 for rom
 */

`ifdef TESTBENCH_VCS
`include "pa_chip_param.v"
`else
`include "../pa_chip_param.v"
`endif

module pa_perips_tcm2 (
    input  wire                         clk_i,
    input  wire                         rst_n_i,

    input  wire [`ADDR_BUS_WIDTH-1:0]   addr1_i,
    input  wire                         rd1_i,
    input  wire                         we1_i,
    input  wire [2:0]                   size1_i,
    input  wire [`DATA_BUS_WIDTH-1:0]   data1_i,
    output wire [`DATA_BUS_WIDTH-1:0]   data1_o,

    input  wire [`ADDR_BUS_WIDTH-1:0]   addr2_i,
    input  wire                         rd2_i,
    output wire [`DATA_BUS_WIDTH-1:0]   data2_o
);


`ifdef MEMORY_MODEL_REG

reg  [7:0]                              _ram[0:`MEM_SIZE*1024-1];

wire [`ADDR_BUS_WIDTH-1:0]              index1;
wire [`ADDR_BUS_WIDTH-1:0]              index2;

assign index1[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr1_i[27:2]};
assign index2[`ADDR_BUS_WIDTH-1:0] = {2'b0, 4'b0, addr2_i[27:2]};

reg  [`DATA_BUS_WIDTH-1:0]              _data1;
reg  [`DATA_BUS_WIDTH-1:0]              _data2;

always @ (posedge clk_i or negedge rst_n_i) begin
    if (!rst_n_i) begin
        _data1[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
    end
    else if (rd1_i) begin
        _data1[`DATA_BUS_WIDTH-1:0] = {_ram[index1*4+3], _ram[index1*4+2], _ram[index1*4+1], _ram[index1*4+0]};
    end
end

always @ (posedge clk_i or negedge rst_n_i) begin
    if (!rst_n_i) begin
        _data2[`DATA_BUS_WIDTH-1:0] = `ZERO_WORD;
    end
    else if (rd2_i) begin
        _data2[`DATA_BUS_WIDTH-1:0] = {_ram[index2*4+3], _ram[index2*4+2], _ram[index2*4+1], _ram[index2*4+0]};
    end
end

`endif // `ifdef MEMORY_MODEL_REG


`ifdef MEMORY_MODEL_BRAM

wire [`DATA_BUS_WIDTH-1:0]              _data1;
wire [`DATA_BUS_WIDTH-1:0]              _data2;

Gowin_DPB_32x8k _rom_0 (
    .douta(_data1), //output [31:0] douta
    .doutb(_data2), //output [31:0] doutb
    .clka(clk_i), //input clka
    .ocea(`VALID), //input ocea
    .cea(`VALID), //input cea
    .reseta(~rst_n_i), //input reseta
    .wrea(we1_i), //input wrea
    .clkb(clk_i), //input clkb
    .oceb(`VALID), //input oceb
    .ceb(`VALID), //input ceb
    .resetb(~rst_n_i), //input resetb
    .wreb(1'b0), //input wreb
    .ada(addr1_i[14:2]), //input [12:0] ada
    .dina(data1_i), //input [31:0] dina
    .adb(addr2_i[14:2]), //input [12:0] adb
    .dinb(32'b0) //input [31:0] dinb
);

`endif // `ifdef MEMORY_MODEL_BRAM


assign data1_o[`DATA_BUS_WIDTH-1:0] = _data1[`DATA_BUS_WIDTH-1:0];
assign data2_o[`DATA_BUS_WIDTH-1:0] = _data2[`DATA_BUS_WIDTH-1:0];

endmodule
